package cn.net.xyan.tts.utils;



import net.sourceforge.lame.lowlevel.LameEncoder;
import net.sourceforge.lame.mp3.Lame;
import net.sourceforge.lame.mp3.MPEGMode;

import javax.sound.sampled.*;
import java.io.*;

/**
 * Created by zarra on 2017/1/25.
 */
public class AudioUtils {
    public static void playAudio(AudioInputStream stream) throws Exception {
        Line.Info linfo = new Line.Info(Clip.class);
        Line line = AudioSystem.getLine(linfo);
        final Clip clip = (Clip) line;
        clip.open(stream);
        Thread t = new Thread(new Runnable() {
            Boolean w = true;

            @Override
            public void run() {
                clip.addLineListener(new LineListener() {
                    @Override
                    public void update(LineEvent event) {
                        if (LineEvent.Type.STOP.equals(event.getType())) {
                            synchronized (w) {
                                w.notifyAll();
                            }
                        }
                    }
                });
                clip.start();
                try {
                    synchronized (w) {
                        w.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        t.join();
    }

    public static void saveAudio(OutputStream outputStream, AudioInputStream stream) throws IOException {
        AudioSystem.write(stream, AudioFileFormat.Type.WAVE, outputStream);
    }

    public static void saveMp3Audio(OutputStream out, AudioInputStream stream)throws IOException {

        LameEncoder encoder = new LameEncoder(stream.getFormat(), 64, MPEGMode.MONO, Lame.QUALITY_MIDDLE, false);

        int bufferSize = encoder.getPCMBufferSize();

        byte[] buffer = new byte[bufferSize];

        int readN;

        ByteArrayOutputStream tOUT = new ByteArrayOutputStream();

        do{
            readN = stream.read(buffer,0,bufferSize);
            if (readN>0){
                tOUT.write(buffer,0,readN);
            }
        }while (readN>0);



        byte[] pcm = tOUT.toByteArray();


        int bytesToTransfer = Math.min(buffer.length, pcm.length);
        int bytesWritten;
        int currentPcmPosition = 0;
        while (0 < (bytesWritten = encoder.encodeBuffer(pcm, currentPcmPosition, bytesToTransfer, buffer))) {
            currentPcmPosition += bytesToTransfer;
            bytesToTransfer = Math.min(buffer.length, pcm.length - currentPcmPosition);

            out.write(buffer, 0, bytesWritten);
        }

        encoder.close();

    }

    public static void saveAudio(File file, AudioInputStream stream) throws IOException {
        saveAudio(new FileOutputStream(file), stream);
    }
}
